# -*- encoding: utf-8 -*-
from datetime import datetime

from . import validator
from . import helper


@validator.check_id_no
def valid_id_no(id_no: str, strict_mode=False) -> bool:
    """
    校验身份证是否合法
    :param id_no: 身份证号码
    :param strict_mode: 是否启用严格模式
    :return:
    """
    id_no = str(id_no)
    code = helper.get_no_args(id_no)
    info = helper.get_address_info(code['address_code'], code['birthday_code'], strict_mode)
    if not validator.check_address_code(code['address_code'], info):
        return False
    if not validator.check_birthday_code(code['birthday_code']):
        return False
    if not validator.check_order_no(code['order_code']):
        return False
    if code['type'] == 15:
        return True
    gen_check_bit = helper.generator_check_bit(code['body'])
    if code['check_bit'] != gen_check_bit:
        return False

    return True


@validator.check_id_no
def id_info(id_no: str, translation=False, strict_mode=False):
    """
    获取身份证信息
    :param id_no:身份证号码
    :param translation: 是否将地址转换为最新的地址
    :param strict_mode: 是否启用严格模式
    :return:
    """
    if not valid_id_no(id_no, strict_mode):
        return False
    code = helper.get_no_args(id_no)
    address_info = helper.get_address_info(code['address_code'], code['birthday_code'], strict_mode)
    info = dict()
    info['address_code'] = code['address_code']
    info['abandoned'] = helper.get_abandoned(code['address_code'])
    info['address'] = address_info['province'] + address_info['city'] + address_info['district']
    info['address_tree'] = [address_info['province'], address_info['city'], address_info['district']]
    if translation:
        translation, translation_tree = helper.get_translation(code['address_code'], code['birthday_code'])
        info['address_translation'] = translation
        info['address_translation_tree'] = translation_tree
    info['age'] = datetime.now().year - int(code['birthday_code'][0:4])
    info['birthday_code'] = code['birthday_code'][0:4] + '-' + code['birthday_code'][4:6] + '-' + code['birthday_code'][
                                                                                                  6:8]
    info['constellation'] = helper.get_constellation(code['birthday_code'])
    info['chinese_zodiac'] = helper.get_chinese_zodiac(code['birthday_code'])
    info['sex'] = 0 if int(code['order_code']) % 2 == 0 else 1
    info['length'] = code['type']
    info['check_bit'] = code['check_bit']

    return info


def fake_id_no(mkmt: bool = True, address: str = None, birthday: str = None, sex: int = None):
    """
    伪造身份证
    :param mkmt:是否为港澳台身份证
    :param address:地址
    :param birthday:出生年月日
    :param sex:性别
    :return:
    """
    address_code = helper.generator_address_code(address)
    birthday_code = helper.generator_birthday_code(address_code, address, birthday)
    order_code = helper.generator_order_code(sex)

    if not mkmt:
        return address_code + birthday_code[2:] + order_code

    body = address_code + birthday_code + order_code
    check_bit = helper.generator_check_bit(body)

    return body + check_bit


def upgrade_id(id_card):
    """
    身份证号码升级（15 位升级为 18 位）
    :param id_card:
    :return:
    """
    if not valid_id_no(id_card):
        return False
    code = helper.get_no_args(id_card)
    body = code['address_code'] + code['birthday_code'] + code['order_code']
    return body + helper.generator_check_bit(body)
